package engine.resource.inputfile;

import engine.entities.Mob.MobSpriteSet;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import engine.game.gfx.ColoredSprite;
import engine.game.gfx.SpriteSheet;
import engine.game.level.tiles.AnimatedTile;
import engine.game.level.tiles.BasicTile;
import engine.resource.ResourceInputFile;
import engine.resource.Resources;

public class GraphicConfigFile extends ConfigFile {

    public GraphicConfigFile(File file) {
        super(file);
    }

    public GraphicConfigFile(String path) {
        super(path);
    }

    @Override
    public void readData() {
        super.readData();

        ConfigNode spriteSheetNode = nodes.get("SPRITESHEETS");
        if (spriteSheetNode != null) {
            Map<String, ConfigNode> sheetNodes = spriteSheetNode.getNodes();
            for (String name : sheetNodes.keySet()) {
                try {
                    ConfigNode sheetNode = sheetNodes.get(name);
                    String path = ResourceInputFile.getFolderFrom(filePath) + sheetNode.value("PATH");
                    int unitSize = Integer.parseInt(sheetNode.value("UNITSIZE"));
                    Resources.addSpriteSheet(name, new SpriteSheet(path, unitSize));
                }
                catch (Exception e) {
                    logger.log(e);
                    e.printStackTrace();
                }
            }
        }
        
        ConfigNode spritesNode = nodes.get("SPRITES");
        if (spritesNode != null) {
            Map<String, ConfigNode> spriteNodes = spritesNode.getNodes();
            for (String name : spriteNodes.keySet()) {
                try {
                    ConfigNode spriteNode = spriteNodes.get(name);
                    Resources.addSprite(name, getColoredSpriteFrom(spriteNode));
                }
                catch (Exception e) {
                    logger.log(e);
                }
            }
        }

        ConfigNode tileNode = nodes.get("TILES");
        if (tileNode != null) {
            ConfigNode basicTileNode = tileNode.node("BASICTILES");
            ConfigNode animatedTileNode = tileNode.node("ANIMATEDTILES");

            Map<String, ConfigNode> basicTileNodes = basicTileNode.getNodes();
            for (String name : basicTileNodes.keySet()) {
                try {
                    ConfigNode node = basicTileNodes.get(name);
                    Resources.addTile(name, getBasicTileFrom(name, node));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }

            Map<String, ConfigNode> animatedTileNodes = animatedTileNode.getNodes();
            for (String name : animatedTileNodes.keySet()) {
                try {
                    ConfigNode node = animatedTileNodes.get(name);
                    Resources.addTile(name, getAnimatedTileFrom(name, node));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        ConfigNode spriteSetNode = nodes.get("SPRITESETS");
        if (spriteSetNode != null) {
            Map<String, ConfigNode> setNodes = spriteSetNode.getNodes();
            for (String name : setNodes.keySet() ) {
                ConfigNode node = setNodes.get(name);
                Resources.addSpriteSet(name, getSpriteSetFrom(node));
            }
        }

    }

    private BasicTile getBasicTileFrom(String name, ConfigNode node) {
        ConfigNode spriteNode = node.node("SPRITE0");
        ColoredSprite cSprite = getColoredSpriteFrom(spriteNode);
        boolean isSolid = Boolean.parseBoolean(node.value("ISSOLID"));

        return new BasicTile(name, cSprite, isSolid);
    }

    private AnimatedTile getAnimatedTileFrom(String name, ConfigNode node) {

        List<ColoredSprite> sprites = new ArrayList<>();
        int spriteNumber = 0;
        boolean isSolid = false;

        try {
            while (node.hasNode("SPRITE" + spriteNumber)) {
                sprites.add(getColoredSpriteFrom(node.node("SPRITE" + spriteNumber)));
                spriteNumber++;
            }

            isSolid = Boolean.parseBoolean(node.value("ISSOLID"));
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return new AnimatedTile(name, sprites, isSolid);
    }

    private MobSpriteSet getSpriteSetFrom(ConfigNode node) {
        MobSpriteSet set = new MobSpriteSet();
        Map<String, ConfigNode> spriteNodes = node.getNodes();
        
        set.setFrontFaceSprite(getColoredSpriteFrom(spriteNodes.get("FRONTFACESPRITE")));
        set.setBackFaceSprite(getColoredSpriteFrom(spriteNodes.get("BACKFACESPRITE")));
        set.setLeftFaceSprite(getColoredSpriteFrom(spriteNodes.get("LEFTFACESPRITE")));
        set.setRightFaceSprite(getColoredSpriteFrom(spriteNodes.get("RIGHTFACESPRITE")));
        
        set.setFrontWalkSprite1(getColoredSpriteFrom(spriteNodes.get("FRONTWALKSPRITE1")));
        set.setFrontWalkSprite2(getColoredSpriteFrom(spriteNodes.get("FRONTWALKSPRITE2")));
        set.setBackWalkSprite1(getColoredSpriteFrom(spriteNodes.get("BACKWALKSPRITE1")));
        set.setBackWalkSprite2(getColoredSpriteFrom(spriteNodes.get("BACKWALKSPRITE2")));
        
        set.setRightWalkSprite(getColoredSpriteFrom(spriteNodes.get("RIGHTWALKSPRITE")));
        set.setLeftWalkSprite(getColoredSpriteFrom(spriteNodes.get("LEFTWALKSPRITE")));
        
        set.setRightAttackSprite(getColoredSpriteFrom(spriteNodes.get("RIGHTATTACKSPRITE")));
        set.setLeftAttackSprite(getColoredSpriteFrom(spriteNodes.get("LEFTATTACKSPRITE")));
        set.setBackAttackSprite(getColoredSpriteFrom(spriteNodes.get("BACKATTACKSPRITE")));
        set.setFrontAttackSprite(getColoredSpriteFrom(spriteNodes.get("FRONTATTACKSPRITE")));
        
        set.setCastSprite(getColoredSpriteFrom(spriteNodes.get("CASTSPRITE")));
        set.setDeadSprite(getColoredSpriteFrom(spriteNodes.get("DEADSPRITE")));
        
        return set;
    }
    
}
